package com.sinbader.xiaole.appapi.service;

import cn.stylefeng.roses.kernel.model.response.ResponseData;
import com.sinbader.xiaole.common.entity.TencentSmsRecord;
import com.sinbader.xiaole.common.enums.RedisKeys;
import com.sinbader.xiaole.common.kit.HttpKit;
import com.sinbader.xiaole.common.kit.TencentSmsKit;
import com.sinbader.xiaole.common.kit.tencent.TencentAccount;
import com.sinbader.xiaole.common.kit.tencent.TencentSmsRequest;
import com.sinbader.xiaole.common.service.TencentSmsRecordService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@Service
public class SmsService {

	private static TencentAccount tencentAccount = new TencentAccount();

	private static final String SmsRegisterTemplateId = "568950";
	private static final String SmsResetPasswordTemplateId = "568955";
	private static final String SmsLoginTemplateId = "568943";
	private static final String SmsBindPhoneTemplateId = "585982";

	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private TencentSmsRecordService tencentSmsRecordService;


	public void sendRegistSmsCode(String phone, String code) {
		TencentSmsRequest smsRequest = TencentSmsRequest.getDefault();
		smsRequest.setParams(new String[]{code});
		smsRequest.setPhone(phone);
		smsRequest.setPurpose("register");
		smsRequest.setTemplateId(SmsRegisterTemplateId);
		TencentSmsRecord record = TencentSmsKit.sendSms(tencentAccount, smsRequest);
		tencentSmsRecordService.save(record);
		if("OK".equals(record.getResponseCode())) {
			String redisKey = RedisKeys.getRegistSmsCode(phone);
			stringRedisTemplate.opsForValue().set(redisKey, code, 10L, TimeUnit.MINUTES);
		}
	}

	public void sendResetPasswordSmsCode(String phone, String code) {
		TencentSmsRequest smsRequest = TencentSmsRequest.getDefault();
		smsRequest.setParams(new String[]{code});
		smsRequest.setPhone(phone);
		smsRequest.setPurpose("resetPassword");
		smsRequest.setTemplateId(SmsResetPasswordTemplateId);
		TencentSmsRecord record = TencentSmsKit.sendSms(tencentAccount, smsRequest);
		tencentSmsRecordService.save(record);
		if("OK".equals(record.getResponseCode())) {
			String redisKey = RedisKeys.getResetPasswordSmsCode(phone);
			stringRedisTemplate.opsForValue().set(redisKey, code, 10L, TimeUnit.MINUTES);
		}
	}

	public void sendLoginSmsCode(String phone, String code) {
		TencentSmsRequest smsRequest = TencentSmsRequest.getDefault();
		smsRequest.setParams(new String[]{code});
		smsRequest.setPhone(phone);
		smsRequest.setPurpose("login");
		smsRequest.setTemplateId(SmsLoginTemplateId);
		TencentSmsRecord record = TencentSmsKit.sendSms(tencentAccount, smsRequest);
		tencentSmsRecordService.save(record);
		if("OK".equals(record.getResponseCode())) {
			String redisKey = RedisKeys.getLoginSmsCode(phone);
			stringRedisTemplate.opsForValue().set(redisKey, code, 10L, TimeUnit.MINUTES);
		}
	}

	public void sendBindPhoneSmsCode(String phone, String code) {
		TencentSmsRequest smsRequest = TencentSmsRequest.getDefault();
		smsRequest.setParams(new String[]{code});
		smsRequest.setPhone(phone);
		smsRequest.setPurpose("resetPassword");
		smsRequest.setTemplateId(SmsBindPhoneTemplateId);
		TencentSmsRecord record = TencentSmsKit.sendSms(tencentAccount, smsRequest);
		tencentSmsRecordService.save(record);
		if("OK".equals(record.getResponseCode())) {
			String redisKey = RedisKeys.getBindPhoneSmsCode(phone);
			stringRedisTemplate.opsForValue().set(redisKey, code, 10L, TimeUnit.MINUTES);
		}
	}

	public int countByPhoneAfterTime(String phone, Date time) {
		return 0;
	}
	public int countByIpAfterTime(String ip, Date time) {
		return 0;
	}

	public ResponseData checkSendSmsCode(String phone, String redisKey1Min) {
		// 检查是否有参数手机号
		if(StringUtils.isBlank(phone)) {
			return ResponseData.error("请输入手机号");
		}

		// 手机号是否有效
		phone = phone.trim();
		boolean isPhone = Pattern.compile("1\\d{10}").matcher(phone).matches();
		if(!isPhone) {
			return ResponseData.error("手机号无效");

		}

		// 检查是否可以重发 （判断同一手机号， 1分钟内不可重复发短信）
//		String registCodeResendKey = RedisKeys.getRegistSmsCode1Min(phone);
		String registCode = stringRedisTemplate.opsForValue().get(redisKey1Min);
		if(StringUtils.isNotBlank(registCode)) {
			return ResponseData.error("1分钟内不能重发");
		}

		// 检查是否可以重发（判断最近一个小时的发送总数， 根据同手机号判断）
		Date date = DateUtils.addMinutes(new Date(), -60);
		long count = countByPhoneAfterTime(phone, date);
		if(count>=10) {
			return ResponseData.error("您操作频繁，请稍后重试!");
		}

		// 检查是否可以重发（判断同一IP一天内的发送数）
		Date yesterday = DateUtils.addDays(new Date(), -1);
		String ip = HttpKit.getClientIp();
		long dayCount = countByIpAfterTime(ip, yesterday);
		if(dayCount>=20) {
			return ResponseData.error("您操作太频繁，请稍后重试!");
		}

		return null; // check pass
	}

	public String genCode(String redisKey) {
		String code = stringRedisTemplate.opsForValue().get(redisKey);
		if(StringUtils.isBlank(code)) {
			code = RandomStringUtils.random(6, false, true);
		}
		return code;
	}

}
